package com.google.code.mergeinformer.util;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Map;
import java.util.Properties;

/**
 * @author Dmitry Golubev
 */
public class AppUtils {

    private AppUtils() {
    }

    private static final Logger logger = LoggerFactory.getLogger(AppUtils.class);

    private static final String RESOURCE_PATH = "/app.properties";

    private static final Environment ENVIRONMENT;

    private static final Properties properties;

    static {
        final InputStream is = AppUtils.class.getResourceAsStream(RESOURCE_PATH);
        if (is == null) {
            throw new RuntimeException(RESOURCE_PATH + " does not exist \n" +
                    "Run mvn:install to generate default application properties");
        }

        properties = new Properties();
        try (final Reader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is), "UTF-8"))) {
            properties.load(reader);
        } catch (IOException e) {
            throw new RuntimeException("Unexpected error during application properties loading", e);
        }

        final String env = properties.getProperty("app.env");
        if (StringUtils.isEmpty(env)) {
            logger.warn("No property app.env was specified! Using prod as default environment");
            ENVIRONMENT = Environment.PRODUCTION;
        } else {
            ENVIRONMENT = Environment.lookup(env);
        }
    }

    public static Map getProperties() {
        return properties;
    }

    /**
     * Searches for property with given key
     * @param key key of property to retrieve
     * @return property value or null if no property with given key was found
     */
    public static String getProperty(String key) {
        return properties.getProperty(key);
    }

    /**
     * Searches for property with given key
     * @param key key of property to retrieve
     * @param defaultValue value to be returned if no property with given key was found
     * @return property value or defaultValue if no property with given key was found
     */
    public static String getProperty(String key, String defaultValue) {
        return properties.getProperty(key, defaultValue);
    }

    /**
     * Searches for Integer property with given key
     * @param key key of property to retrieve
     * @return property value or null if no property with given key was found
     */
    public static Integer getPropertyInt(String key) {
        final String value = properties.getProperty(key);
        return value != null ? Integer.valueOf(value) : null;
    }

    /**
     * Returns current environment
     * @return current environment
     */
    public static Environment getEnvironment() {
        return ENVIRONMENT;
    }

    /**
     * Check if application is running in production mode
     * @return true if application is running in production mode, otherwise false
     */
    public static boolean isProd() {
        return Environment.PRODUCTION == ENVIRONMENT;
    }

    /**
     * Check if application is running in development mode
     * @return true if application is running in development mode, otherwise false
     */
    public static boolean isDev() {
        return Environment.DEVELOPMENT == ENVIRONMENT;
    }

    public static enum Environment {
        PRODUCTION("prod"), DEVELOPMENT("dev");

        private final String value;

        private Environment(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        public static Environment lookup(String value) {
            for (Environment environment : Environment.values()) {
                if (environment.getValue().equals(value)) {
                    return environment;
                }
            }
            throw new IllegalArgumentException("Unknown environment " + value);
        }
    }
}
